using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using twistmachinev2.OPCUA;

namespace twistmachinev2.TwistControl
{
    /// <summary>
    /// 绞线机显示控件
    /// 模拟绞线机界面，包含多个可独立绑定PropertyName的数字显示框
    /// </summary>
    public class TwistMachineDisplay : UserControl
    {
        #region 私有字段
        private DynamicDataModel _dataModel;
        private Timer _updateTimer;
        private bool _isUpdating = false;
        
        // 数字显示框
        private DataBindingLabel _topLeftLabel;
        private DataBindingLabel _topCenterLabel;
        private DataBindingLabel _leftLabel;
        private DataBindingLabel _centerLabel;
        private DataBindingLabel _rightLabel;
        
        // 绞线机图形元素
        private Panel _machineFrame;
        private Panel _wireContainer;
        #endregion

        #region 公共属性
        /// <summary>
        /// 关联的数据模型
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DynamicDataModel DataModel
        {
            get { return _dataModel; }
            set
            {
                if (_dataModel != value)
                {
                    // 取消旧模型的事件订阅
                    if (_dataModel != null)
                    {
                        _dataModel.PropertyChanged -= OnDataModelPropertyChanged;
                    }

                    _dataModel = value;

                    // 订阅新模型的事件
                    if (_dataModel != null)
                    {
                        _dataModel.PropertyChanged += OnDataModelPropertyChanged;
                    }

                    // 更新所有标签的数据模型
                    UpdateAllLabelsDataModel();
                }
            }
        }

        /// <summary>
        /// 左上角数字显示框的属性名称
        /// </summary>
        [Category("Data Binding")]
        [Description("左上角数字显示框绑定的属性名称")]
        [Editor(typeof(PropertyNameEditor), typeof(UITypeEditor))]
        public string TopLeftPropertyName { get; set; } = "";

        /// <summary>
        /// 上方中央数字显示框的属性名称
        /// </summary>
        [Category("Data Binding")]
        [Description("上方中央数字显示框绑定的属性名称")]
        [Editor(typeof(PropertyNameEditor), typeof(UITypeEditor))]
        public string TopCenterPropertyName { get; set; } = "";

        /// <summary>
        /// 左侧数字显示框的属性名称
        /// </summary>
        [Category("Data Binding")]
        [Description("左侧数字显示框绑定的属性名称")]
        [Editor(typeof(PropertyNameEditor), typeof(UITypeEditor))]
        public string LeftPropertyName { get; set; } = "";

        /// <summary>
        /// 中央数字显示框的属性名称
        /// </summary>
        [Category("Data Binding")]
        [Description("中央数字显示框绑定的属性名称")]
        [Editor(typeof(PropertyNameEditor), typeof(UITypeEditor))]
        public string CenterPropertyName { get; set; } = "";

        /// <summary>
        /// 右侧数字显示框的属性名称
        /// </summary>
        [Category("Data Binding")]
        [Description("右侧数字显示框绑定的属性名称")]
        [Editor(typeof(PropertyNameEditor), typeof(UITypeEditor))]
        public string RightPropertyName { get; set; } = "";

        /// <summary>
        /// 数字显示格式
        /// </summary>
        [Category("Data Binding")]
        [Description("数字显示格式，如F0表示整数")]
        [DefaultValue("F0")]
        public string DisplayFormat { get; set; } = "F0";

        /// <summary>
        /// 默认值
        /// </summary>
        [Category("Data Binding")]
        [Description("当数据为空或获取失败时显示的默认值")]
        [DefaultValue(0)]
        public object DefaultValue { get; set; } = 0;

        /// <summary>
        /// 是否启用自动更新
        /// </summary>
        [Category("Data Binding")]
        [Description("是否启用定时自动更新显示")]
        [DefaultValue(false)]
        public bool AutoUpdate { get; set; } = false;

        /// <summary>
        /// 自动更新间隔（毫秒）
        /// </summary>
        [Category("Data Binding")]
        [Description("自动更新间隔，单位毫秒")]
        [DefaultValue(1000)]
        public int UpdateInterval { get; set; } = 1000;
        #endregion

        #region 构造函数
        public TwistMachineDisplay()
        {
            InitializeComponent();
            InitializeTimer();
        }
        #endregion

        #region 初始化方法
        private void InitializeComponent()
        {
            // 设置控件基本属性
            Size = new Size(400, 200);
            BackColor = Color.White;
            BorderStyle = BorderStyle.FixedSingle;

            // 创建机器框架
            CreateMachineFrame();
            
            // 创建数字显示标签
            CreateDataLabels();
            
            // 创建绞线图形
            CreateWireGraphics();
        }

        private void CreateMachineFrame()
        {
            _machineFrame = new Panel
            {
                Location = new Point(10, 10),
                Size = new Size(380, 180),
                BackColor = Color.LightGray,
                BorderStyle = BorderStyle.Fixed3D
            };
            Controls.Add(_machineFrame);
        }

        private void CreateDataLabels()
        {
            // 左上角标签
            _topLeftLabel = new DataBindingLabel
            {
                Location = new Point(20, 20),
                Size = new Size(60, 30),
                BackColor = Color.LightBlue,
                TextAlign = ContentAlignment.MiddleCenter,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Arial", 10, FontStyle.Bold)
            };
            _machineFrame.Controls.Add(_topLeftLabel);

            // 上方中央标签
            _topCenterLabel = new DataBindingLabel
            {
                Location = new Point(160, 20),
                Size = new Size(60, 30),
                BackColor = Color.LightBlue,
                TextAlign = ContentAlignment.MiddleCenter,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Arial", 10, FontStyle.Bold)
            };
            _machineFrame.Controls.Add(_topCenterLabel);

            // 左侧标签
            _leftLabel = new DataBindingLabel
            {
                Location = new Point(20, 80),
                Size = new Size(60, 30),
                BackColor = Color.LightBlue,
                TextAlign = ContentAlignment.MiddleCenter,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Arial", 10, FontStyle.Bold)
            };
            _machineFrame.Controls.Add(_leftLabel);

            // 中央标签
            _centerLabel = new DataBindingLabel
            {
                Location = new Point(160, 80),
                Size = new Size(60, 30),
                BackColor = Color.LightBlue,
                TextAlign = ContentAlignment.MiddleCenter,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Arial", 10, FontStyle.Bold)
            };
            _machineFrame.Controls.Add(_centerLabel);

            // 右侧标签
            _rightLabel = new DataBindingLabel
            {
                Location = new Point(300, 80),
                Size = new Size(60, 30),
                BackColor = Color.LightBlue,
                TextAlign = ContentAlignment.MiddleCenter,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Arial", 10, FontStyle.Bold)
            };
            _machineFrame.Controls.Add(_rightLabel);
        }

        private void CreateWireGraphics()
        {
            _wireContainer = new Panel
            {
                Location = new Point(30, 120),
                Size = new Size(320, 40),
                BackColor = Color.Transparent
            };
            _wireContainer.Paint += WireContainer_Paint;
            _machineFrame.Controls.Add(_wireContainer);
        }

        private void InitializeTimer()
        {
            _updateTimer = new Timer();
            _updateTimer.Tick += UpdateTimer_Tick;
        }
        #endregion

        #region 绘制方法
        private void WireContainer_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // 绘制绞线效果
            DrawTwistedWires(g);
        }

        private void DrawTwistedWires(Graphics g)
        {
            int width = _wireContainer.Width;
            int height = _wireContainer.Height;
            int centerY = height / 2;

            // 绘制三根绞合的线
            using (Pen bluePen = new Pen(Color.Blue, 3))
            using (Pen redPen = new Pen(Color.Red, 3))
            using (Pen greenPen = new Pen(Color.Green, 3))
            {
                // 绘制波浪形的绞线
                for (int x = 0; x < width; x += 2)
                {
                    double angle = (double)x / 20 * Math.PI;
                    
                    // 蓝线
                    int y1 = centerY + (int)(Math.Sin(angle) * 8);
                    int y2 = centerY + (int)(Math.Sin(angle + 0.1) * 8);
                    g.DrawLine(bluePen, x, y1, x + 2, y2);
                    
                    // 红线
                    int y3 = centerY + (int)(Math.Sin(angle + Math.PI * 2 / 3) * 8);
                    int y4 = centerY + (int)(Math.Sin(angle + 0.1 + Math.PI * 2 / 3) * 8);
                    g.DrawLine(redPen, x, y3, x + 2, y4);
                    
                    // 绿线
                    int y5 = centerY + (int)(Math.Sin(angle + Math.PI * 4 / 3) * 8);
                    int y6 = centerY + (int)(Math.Sin(angle + 0.1 + Math.PI * 4 / 3) * 8);
                    g.DrawLine(greenPen, x, y5, x + 2, y6);
                }
            }

            // 绘制机器外框
            using (Pen framePen = new Pen(Color.Black, 2))
            {
                g.DrawRectangle(framePen, 0, 0, width - 1, height - 1);
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 设置数据绑定
        /// </summary>
        public void SetDataBinding(DynamicDataModel dataModel, 
            string topLeftProperty = "", string topCenterProperty = "", 
            string leftProperty = "", string centerProperty = "", string rightProperty = "")
        {
            TopLeftPropertyName = topLeftProperty;
            TopCenterPropertyName = topCenterProperty;
            LeftPropertyName = leftProperty;
            CenterPropertyName = centerProperty;
            RightPropertyName = rightProperty;
            
            DataModel = dataModel; // 最后设置，触发更新
        }

        /// <summary>
        /// 手动刷新显示
        /// </summary>
        public void RefreshDisplay()
        {
            UpdateAllLabels();
        }

        /// <summary>
        /// 启动自动更新
        /// </summary>
        public void StartAutoUpdate()
        {
            if (AutoUpdate && UpdateInterval > 0)
            {
                _updateTimer.Interval = UpdateInterval;
                _updateTimer.Start();
            }
        }

        /// <summary>
        /// 停止自动更新
        /// </summary>
        public void StopAutoUpdate()
        {
            _updateTimer.Stop();
        }
        #endregion

        #region 私有方法
        private void UpdateAllLabelsDataModel()
        {
            if (_dataModel != null)
            {
                _topLeftLabel.SetDataBinding(_dataModel, TopLeftPropertyName, DisplayFormat, DefaultValue);
                _topCenterLabel.SetDataBinding(_dataModel, TopCenterPropertyName, DisplayFormat, DefaultValue);
                _leftLabel.SetDataBinding(_dataModel, LeftPropertyName, DisplayFormat, DefaultValue);
                _centerLabel.SetDataBinding(_dataModel, CenterPropertyName, DisplayFormat, DefaultValue);
                _rightLabel.SetDataBinding(_dataModel, RightPropertyName, DisplayFormat, DefaultValue);
            }
        }

        private void UpdateAllLabels()
        {
            if (_isUpdating) return;
            
            try
            {
                _isUpdating = true;
                
                _topLeftLabel?.RefreshDisplay();
                _topCenterLabel?.RefreshDisplay();
                _leftLabel?.RefreshDisplay();
                _centerLabel?.RefreshDisplay();
                _rightLabel?.RefreshDisplay();
            }
            finally
            {
                _isUpdating = false;
            }
        }

        private void OnDataModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // 检查是否是我们关注的属性
            if (string.IsNullOrEmpty(e.PropertyName) ||
                e.PropertyName == TopLeftPropertyName ||
                e.PropertyName == TopCenterPropertyName ||
                e.PropertyName == LeftPropertyName ||
                e.PropertyName == CenterPropertyName ||
                e.PropertyName == RightPropertyName)
            {
                if (InvokeRequired)
                {
                    Invoke(new Action(UpdateAllLabels));
                }
                else
                {
                    UpdateAllLabels();
                }
            }
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            UpdateAllLabels();
        }
        #endregion

        #region 重写方法
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            
            // 控件创建后启动自动更新
            if (AutoUpdate)
            {
                StartAutoUpdate();
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // 清理资源
                StopAutoUpdate();
                _updateTimer?.Dispose();
                
                if (_dataModel != null)
                {
                    _dataModel.PropertyChanged -= OnDataModelPropertyChanged;
                }
            }
            base.Dispose(disposing);
        }
        #endregion
    }

    /// <summary>
    /// 数据绑定标签控件
    /// </summary>
    internal class DataBindingLabel : Label
    {
        private DynamicDataModel _dataModel;
        private string _propertyName;
        private string _displayFormat;
        private object _defaultValue;
        private bool _isUpdating = false;

        public void SetDataBinding(DynamicDataModel dataModel, string propertyName, string displayFormat = null, object defaultValue = null)
        {
            _dataModel = dataModel;
            _propertyName = propertyName;
            _displayFormat = displayFormat;
            _defaultValue = defaultValue;
            RefreshDisplay();
        }

        public void RefreshDisplay()
        {
            if (_isUpdating) return;

            try
            {
                _isUpdating = true;

                if (_dataModel == null || string.IsNullOrEmpty(_propertyName))
                {
                    Text = GetDefaultDisplayText();
                    return;
                }

                var value = _dataModel.GetValue(_propertyName);
                Text = FormatValue(value);
            }
            catch (Exception ex)
            {
                Text = GetDefaultDisplayText();
                System.Diagnostics.Debug.WriteLine($"DataBindingLabel更新显示失败: {ex.Message}");
            }
            finally
            {
                _isUpdating = false;
            }
        }

        private string FormatValue(object value)
        {
            if (value == null)
            {
                return GetDefaultDisplayText();
            }

            if (!string.IsNullOrEmpty(_displayFormat) && value is IFormattable formattable)
            {
                return formattable.ToString(_displayFormat, null);
            }
            else
            {
                return value.ToString();
            }
        }

        private string GetDefaultDisplayText()
        {
            return _defaultValue?.ToString() ?? "0";
        }
    }
}